(function () {
	var imp, db, aliases, to, from;
	importer();
	params();

	panda.db = {
		get: function(name) {
			return proxy(db.getCollection(name));
		},
		eval: function eval(func) {
			if (func instanceof Function) {
				func = '(' + func + '())';
			}
	
			db.eval(func);
		},
		__noSuchMethod__: delegate
	};

	function importer() {
		imp = JavaImporter(com.mongodb, com.mongodb.rhino);
	}

	function params() {
		db = imp.Mongo().getDB(config.db.name);
		aliases = { get: 'findOne', list: 'find' };
		to = imp.BSON.to;
		from = imp.BSON.from;
	}

	function delegate(name, args) {
		return db[name].apply(db, args);
	}

	function proxy(target) {
		return {
			__noSuchMethod__: function(name, args) {
				var cursor = true;
				if (name.indexOf('$') === 0) {
					cursor = false;
					name = name.substr(1);
				};

				name = aliases[name] || name;

			 	for (var i = 0; i < args.length; ++i) {
			 		if (typeof args[i] === 'object') {
			 			args[i] = to(args[i]);
			 		}
			 	}

				var ret = target[name].apply(target, args);

				if (ret instanceof imp.DBCursor) {
					ret = cursor ?  proxy(ret) : from(ret.toArray());
				} else if (ret instanceof imp.DBObject) {
					ret = from(ret);
				}

				return ret;
			}
		};
	};
}());
